import re
import time
from django.contrib.auth import get_user_model
from rest_framework import serializers
from rest_framework_jwt.settings import api_settings
from finance_c2c.settings import REGEX_MOBILE
from .models import LevelDesc
from .utils import jwt_payload_handler
from apps.user_operation.APIClient import api_client
from apps.czb.models import ApiChannel
from apps.czb.client import get_czb_api

jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
UserModel = get_user_model()


class BaseSerializers(serializers.Serializer):
    appKey = serializers.CharField(label="appKey", required=False, allow_null=True, allow_blank=True)
    timeStamp = serializers.CharField(label="timeStamp", required=False, allow_null=True, allow_blank=True)
    sign = serializers.CharField(label="sign", help_text="sign", required=False, allow_null=True, allow_blank=True)

    def system_validate(self, attrs):
        if attrs.get("timeStamp") and attrs.get("appKey") and attrs.get("sign"):
            return attrs
        else:
            raise serializers.ValidationError(detail="缺少系统级参数(appKey, timeStamp, sign)", code=20400)

    @classmethod
    def compare_time(cls, timestamp):
        """

        :param timestamp:
        :return:
        """
        now_time = int(time.time())
        value = now_time - int(timestamp)
        if abs(value) > 10 * 3600:
            raise serializers.ValidationError(detail="请求时间过期", code=20402)

    @classmethod
    def compare_sign(cls, app_secret, sign, parameters):
        compute_sign = api_client.get_sign(parameters, app_secret)
        if sign != compute_sign:
            raise serializers.ValidationError(detail="签名验证失败", code=20401)

    @classmethod
    def get_channel(cls, app_key):
        try:
            instance = ApiChannel.objects.get(app_key=app_key, status=True)
            setattr(cls, "api_channel", instance)
            czb_api = get_czb_api(instance.app_key)
            setattr(cls, "czb_api", czb_api)
            return instance
        except Exception as e:
            raise serializers.ValidationError(detail="非法请求，未知的调用方", code=20404)

    def validate(self, attrs):
        self.system_validate(attrs)
        app_key = attrs["appKey"]
        sign = attrs.pop("sign")
        instance = self.get_channel(app_key)
        app_secret = instance.app_secret
        self.compare_sign(app_secret, sign, attrs)
        attrs.pop("appKey")
        attrs.pop("timeStamp")
        return attrs

    def create(self, validated_data):
        pass

    def update(self, instance, validated_data):
        pass

    class Meta:
        fields = ("appKey", "timeStamp", "sign")


# API输出用户登录
class APILoginSerializer(BaseSerializers):
    mobile = serializers.CharField(label="手机号", write_only=True, required=False, allow_null=True, allow_blank=True)

    def validate_mobile(self, mobile):
        if re.match(REGEX_MOBILE, mobile):
            return mobile
        else:
            raise serializers.ValidationError(detail="手机号不合法", code=400)

    def create(self, validated_data):
        mobile = validated_data["mobile"]
        self.czb_api.platform_login(mobile) # 去车主邦注册
        user, created = UserModel.objects.get_or_create(mobile=mobile, username=mobile)
        user.level = LevelDesc.objects.get(level=1)
        user.save()
        payload = jwt_payload_handler(self, user)
        token = jwt_encode_handler(payload)
        # token = base64.b64encode(token.encode("utf-8"))
        setattr(self, 'object', {"user": user, "token": token})
        return user

    def update(self, instance, validated_data):
        pass

    class Meta:
        fields = ("mobile", "appKey", "timeStamp", "sign",)
